﻿using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace ChangeThemes
{
    public class ThemeProperty
    {
        #region BackgroundProperty

        public static Brush GetBackground(DependencyObject obj)
        {
            return (Brush)obj.GetValue(BackgroundProperty);
        }

        public static void SetBackground(DependencyObject obj, Brush value)
        {
            obj.SetValue(BackgroundProperty, value);
        }

        // Using a DependencyProperty as the backing store for Background.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BackgroundProperty =
            DependencyProperty.RegisterAttached("Background", typeof(Brush), typeof(ThemeProperty), new PropertyMetadata(null, OnBackgroundPropertyChanged));

        #endregion


        #region ForegroundProperty


        public static Brush GetForeground(DependencyObject obj)
        {
            return (Brush)obj.GetValue(ForegroundProperty);
        }

        public static void SetForeground(DependencyObject obj, Brush value)
        {
            obj.SetValue(ForegroundProperty, value);
        }

        // Using a DependencyProperty as the backing store for Foreground.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ForegroundProperty =
            DependencyProperty.RegisterAttached("Foreground", typeof(Brush), typeof(ThemeProperty), new PropertyMetadata(null, OnForegroundPropertyChanged));

        #endregion

        private static void OnBackgroundPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is FrameworkElement el && e.NewValue is SolidColorBrush newColor)
            {
                if (e.OldValue is SolidColorBrush oldColor)
                {
                    AnimatBrushProperty(el, "Background", newColor, oldColor);
                }
                else
                {
                    AnimatBrushProperty(el, "Background", newColor);
                }
            }
        }

        private static void OnForegroundPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is FrameworkElement el && e.NewValue is SolidColorBrush newColor)
            {
                if (e.OldValue is SolidColorBrush oldColor)
                {
                    AnimatBrushProperty(el, "Foreground", newColor, oldColor);
                }
                else
                {
                    AnimatBrushProperty(el, "Foreground", newColor);
                }
            }
        }

        private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e, string propertyName)
        {
            if (d is FrameworkElement el && e.NewValue is SolidColorBrush newColor)
            {
                if (e.OldValue is SolidColorBrush oldColor)
                {
                    AnimatBrushProperty(el, propertyName, newColor, oldColor);
                }
                else
                {
                    AnimatBrushProperty(el, propertyName, newColor);
                }
            }
        }

        private static void AnimatBrushProperty(FrameworkElement el, string propertyName, SolidColorBrush newColor, SolidColorBrush? oldColor = null)
        {
            var prop = el.GetType().GetProperty(propertyName);
            if (prop is null)
            {
                return;
            }

            var newBrush = prop.GetValue(el) as SolidColorBrush;
            if (newBrush == null)
            {
                newBrush = new SolidColorBrush(newColor.Color);
                prop.SetValue(el, newBrush);
            }
            var colorAnimation = new ColorAnimation()
            {
                To = newColor.Color,
                Duration = new Duration(TimeSpan.FromSeconds(0.2))
            };
            if (oldColor != null)
            {
                colorAnimation.From = oldColor.Color;
            }

            newBrush.BeginAnimation(SolidColorBrush.ColorProperty, colorAnimation);
            //newBrush.BeginAnimation(BackgroundProperty, colorAnimation);
        }
    }
}
